package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.templates.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.CommentApi;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;

import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: tanhua
 * @description:
 * @author: MR.peng
 * @create: 2022-03-12 03:12
 **/

@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;


    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @DubboReference
    private  CommentApi commentApi;

    @Autowired
    private MqMessageService mqMessageService;

    @DubboReference
    private VisitorsApi visitorsApi;


    /*
    * 保存，发布动态
    *
    * */
    public void movements(MultipartFile[] imageContenet, String textContent,
                          String location, String longitude, String latitude) throws IOException {

        //1.构建动态对象
        Movement movement = new Movement();
        movement.setUserId(UserHolder.getUserId());
        movement.setTextContent(textContent);
        movement.setLatitude(latitude);
        movement.setLongitude(longitude);
        movement.setLocationName(location);
        movement.setCreated(System.currentTimeMillis());
        //2.图片上传到阿里云oss上
        ArrayList<String> medias = new ArrayList<>();
        System.out.println("123"+imageContenet);
        for (MultipartFile multipartFile : imageContenet) {
           String imageurl =  ossTemplate.upload(multipartFile.getInputStream(),multipartFile.getOriginalFilename());
           medias.add(imageurl);
        }

        //3.设置到Movement对象中
        movement.setMedias(medias);
        //4.调用API保存
        String id = movementApi.save(movement);
        //发送MQ消息，用于动态审核
        mqMessageService.sendAudiMessage(id);

    }


    /*
    * 查看我的动态
    * */
    public PageResult all(Integer page, Integer pageSize, Long userId) {
        //1.调用api根据用户id，查询此用户发布的动态列表 List<Movement>
        List<Movement> list =  movementApi.findByUserId(userId,page,pageSize);

        //2.判断动态列表是否为空
        if(CollUtil.isEmpty(list)){
            return new PageResult();
        }
        //3.循环List<Movement> ,一个Movement构建一个MovementVo对象

        //3.1 根据用户id,查询用户信息
        UserInfo userInfo = userInfoApi.findUser(userId);
        List<MovementsVo> vos = new ArrayList<>();
        //3.2 一个Movement构建一个MovementVo对象
        for (Movement movement : list) {
            //需要动态发布人的用户信息
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            //从redis中查询点赞状态，如果有点赞状态，设置为1
            String redisKey = Constants.MOVEMENTS_INTERACT_KEY+vo.getId();
            String hashKey = Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
            Boolean hasKey = redisTemplate.opsForHash().hasKey(redisKey, hashKey);
            if(hasKey){
                vo.setHasLiked(1);
            }

            String loveKey = Constants.MOVEMENT_LOVE_HASHKEY+UserHolder.getUserId();
            Boolean hasloveKey = redisTemplate.opsForHash().hasKey(redisKey, loveKey);
            if(hasloveKey){
                vo.setHasLoved(1);
            }
            vos.add(vo);
        }

        //4.返回
        return new PageResult(page,pageSize,0L,vos);

    }


    /*
    *   查询好友动态:
    *       先关系表，再
    *
    * */
    public PageResult findByFriendsId(Integer page, Integer pageSize) {
        //1.获取当前用户Id,查询的friendId条件
        Long friendId = UserHolder.getUserId();
        //2.调用API根据friendId查询动态列表
        List<Movement> list = movementApi.findByFriendId(friendId,page,pageSize);
        return  initPage(list,page,pageSize);
    }

    //查询推荐动态
    //1。查询redis中的数据
    //2.如果redis中数据不存在，随即从MongoDB中提取动态数据
    public PageResult findByRecommend(Integer page, Integer pageSize) {
        //获取用户id
        Long userId = UserHolder.getUserId();
        //2.从rediss中查询，推荐的动态数据
        String key = "MOVEMENT_RECOMMEND_"+userId;
        String value = redisTemplate.opsForValue().get(key);
        //3.判断动态数据是否存在，如果存在获取数据中的所有id，
        List<Movement> list = new ArrayList<>();
        if(!StringUtils.isEmpty(value)){
            //3.1数据存在，获取数据当中的所有id，调用API根据动态的id列表，查询动态详情 List<Movament>
            String[] movementIds = value.split(",");
            list = movementApi.findByIds(movementIds,page,pageSize);

        }else{
            //3.2数据不存在，调用API随机查询动态列表 List<Movement>
            list  = movementApi.randomMoveent(pageSize);
        }
        //3.1调用API根据动态的id列表，查询动态详情
        //3.2数据不存在，调用API随机查询动态列表，List<Movement>
        //4.调用公共方法构造返回
        PageResult pageResult = initPage(list, page, pageSize);
        return pageResult;
        //5.返回
    }


    private   PageResult initPage(List<Movement> list,Integer page, Integer pageSize){
        //3.判断动态列表是否为空
        if(CollUtil.isEmpty(list)){
            return new PageResult();
        }
        //一次性，将list中所有的动态发布人查询出来
        //1.1提取list中的所有动态的发布人id
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);//list ,属性名，类型

        //1.2调用UserInfoApi,查询多个用户的用户信息
        Map<Long,UserInfo> map = userInfoApi.findByIds(userIds);

        //4.循环List<Movement> ,一个Movement构建一个MovementVo对象
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            //获取动态发布人id
            Long userId = movement.getUserId();
            //查询动态发布人信息
            UserInfo info = map.get(userId);
            //UserInfo user = userInfoApi.findUser(userId);
            //调用MovementVo工具类方法init构建
            MovementsVo vo = MovementsVo.init(info, movement);

            //从redis中查询点赞状态，如果有点赞状态，设置为1
            String redisKey = Constants.MOVEMENTS_INTERACT_KEY+vo.getId();
            String hashKey = Constants.MOVEMENT_LIKE_HASHKEY+UserHolder.getUserId();
            Boolean hasKey = redisTemplate.opsForHash().hasKey(redisKey, hashKey);
            if(hasKey){
                vo.setHasLiked(1);
            }
            //从redis查询喜欢状态，同上
            String loveKey = Constants.MOVEMENT_LOVE_HASHKEY+UserHolder.getUserId();
            Boolean hasloveKey = redisTemplate.opsForHash().hasKey(redisKey, loveKey);
            if(hasloveKey){
                vo.setHasLoved(1);
            }
            vos.add(vo);
        }

        //5.返回
        return new PageResult(page,pageSize,0L,vos);
    }

    /*
    * 根据id查询动态
    * */
    public MovementsVo findById(String id) {
        //调用api查询
        Movement movement = movementApi.findById(id);
        //movement转化为movementVO
        //获取动态发布人
        Long userId = movement.getUserId();
        UserInfo user = userInfoApi.findUser(userId);
        MovementsVo vo = MovementsVo.init(user, movement);
        return  vo;
    }



    //点赞
    public Integer like(String id) {
        Integer commentType = 1;
        //1.调用api保存互动数据，更新动态表
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(id));
        comment.setCreated(System.currentTimeMillis());
        comment.setCommentType(commentType);
        comment.setUserId(UserHolder.getUserId());
        Integer count = commentApi.save(comment);

        //2、将点赞的状态，存入redis(为了方便查询点赞状态)
        String redisKey = Constants.MOVEMENTS_INTERACT_KEY + id;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY +UserHolder.getUserId();
        redisTemplate.opsForHash().put(redisKey,hashKey,"1");

        //3、发送日志消息
        mqMessageService.sendLogMessage(UserHolder.getUserId(),"0203","log.movement",
                id);//用户id，类型，路由键，业务id（动态，视频Id）
        return count;

    }

    //取消点赞
    public Integer dislike(String id) {
        //1.调用api层删除互动数据，更新动态表(用户ID，动态ID，操作类型)
        Integer commentType=  1 ;
        Long userId = UserHolder.getUserId();
        Integer count = commentApi.delete(userId,commentType,id);
        // 2.删除redis中的点赞状态
        String redisKey = Constants.MOVEMENTS_INTERACT_KEY + id;
        String hashKey = Constants.MOVEMENT_LIKE_HASHKEY +UserHolder.getUserId();
        redisTemplate.opsForHash().delete(redisKey,hashKey);
        return count;

    }

    //喜欢
    public Integer love(String movementId) {
        Integer commentType = 3; //喜欢
        //1、调用API保存
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(movementId));
        comment.setCommentType(commentType);
        comment.setUserId(UserHolder.getUserId());
        comment.setCreated(System.currentTimeMillis());
        Integer count = commentApi.save(comment);
        //2、记录喜欢状态到redis中
        String redisKey = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().put(redisKey,hashKey,"1");
        return count;
    }

    //取消喜欢
    public Integer unlove(String movementId) {
        Integer commentType = 3; //喜欢
        Long userId = UserHolder.getUserId();
        //1、调用API删除互动数据，更新动态表(用户id，动态id，操作类型)
        Integer count = commentApi.delete(userId,commentType,movementId);
        //2、删除redis中的，喜欢状态
        String redisKey = Constants.MOVEMENTS_INTERACT_KEY + movementId;
        String hashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getUserId();
        redisTemplate.opsForHash().delete(redisKey,hashKey);
        return count;
    }


    //谁看过我
    public List<TodayBest> visitors() {
        Long userId = UserHolder.getUserId();
        String key = Constants.VISITORS_USER + userId;
        String sTime = redisTemplate.opsForValue().get(key);
        Long time = 0L;
        if (StringUtils.isNotEmpty(sTime)) {
            time = Long.parseLong(sTime);
        }
        List<Visitors> listId = visitorsApi.findById(userId, time);
        List<Long> visitorUserId = CollUtil.getFieldValues(listId, "visitorUserId", Long.class);
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(visitorUserId);//查询所有的来客
        List<TodayBest> vo = new ArrayList<>();
        for (Visitors visitors : listId) {
            TodayBest todayBest = TodayBest.init(userInfoMap.get(visitors.getVisitorUserId()), visitors);
            vo.add(todayBest);
        }
        return vo;
    }
}
